package tinybase.sm;

import java.io.File;
import java.nio.ByteBuffer;

import tinybase.basic.RC;
import tinybase.basic.RedBase;
import tinybase.basic.RedBase.AttrType;
import tinybase.pf.PF_Manager;
import tinybase.rm.RID;
import tinybase.rm.RM_FileHandle;
import tinybase.rm.RM_FileHdr;
import tinybase.rm.RM_Manager;

public class DBCreate {

	//
	// Global PF_Manager and RM_Manager variables
	//
	private PF_Manager pfm;
	private RM_Manager rmm;

	public DBCreate(PF_Manager _pfm, RM_Manager _rmm) {
		this.pfm = _pfm;
		this.rmm = _rmm;
	}

	//
	// createRelcat
	//
	// Desc: Create the relation catalog
	//
	public RC createRelcat() {
		RC rc; 
		RM_FileHandle fh= new RM_FileHandle(); 
		SM_RelcatRec relcatRec= new SM_RelcatRec();
		RID rid= new RID();
		
		if ((rc= rmm.createFile(SM_Internal.RELCAT, 
				SM_RelcatRec.getSM_RelcatRecSize())) != RC.SUCCESS)
			return rc;
		
		if ((rc= rmm.openFile(SM_Internal.ATTRCAT, fh)) != RC.SUCCESS)
			return rc;
		
		SM_RelcatRec.SM_SetRelcatRec(relcatRec, SM_Internal.RELCAT, 
				SM_RelcatRec.getSM_RelcatRecSize(), 4, 0);
		
		ByteBuffer buf= null;
		relcatRec.storeAsBytes(buf);
		if ((rc= fh.insertRec(buf.array(), rid)) != RC.SUCCESS) {
			rmm.closeFile(fh);
			return rc;
		}
			
		SM_RelcatRec.SM_SetRelcatRec(relcatRec, SM_Internal.RELCAT, 
				SM_AttrcatRec.getSM_AttrcatRecSize(), 6, 0);
		
		relcatRec.storeAsBytes(buf);
		if ((rc= fh.insertRec(buf.array(), rid)) != RC.SUCCESS) {
			rmm.closeFile(fh);
			return rc;
		}
		
		if ((rc= rmm.closeFile(fh)) != RC.SUCCESS)
			return rc;
		
		// Return ok
		return RC.SUCCESS;
	}

	//
	// createAttrcat
	//
	// Desc: Create the attribute catalog
	//
	public RC createAttrcat() {
		RC rc= RC.SUCCESS;
		RM_FileHandle fh= new RM_FileHandle();
		SM_AttrcatRec attrcatRec= new SM_AttrcatRec();
		RID rid= new RID();
		ByteBuffer buf= null;
		
		if ((rc= rmm.createFile(SM_Internal.ATTRCAT, 
				SM_AttrcatRec.getSM_AttrcatRecSize())) != RC.SUCCESS)
			return rc;
		
		if ((rc= rmm.openFile(SM_Internal.ATTRCAT, fh)) != RC.SUCCESS)
			return rc;
		
		SM_AttrcatRec.SM_SetAttrcatRec(attrcatRec, SM_Internal.RELCAT, 
				"relName", SM_RelcatRec.getRelNameOffset(), 
				AttrType.STRING, RedBase.MAXNAME, -1);
		
		attrcatRec.storeAsBytes(buf);
		if ((rc= fh.insertRec(buf.array(), rid)) != RC.SUCCESS) {
			rmm.closeFile(fh);
			return rc;
		}

		SM_AttrcatRec.SM_SetAttrcatRec(attrcatRec, SM_Internal.RELCAT, 
				"tupleLength", SM_RelcatRec.getTupleLengthOffset(), 
				AttrType.INT, 4, -1);
		
		attrcatRec.storeAsBytes(buf);
		if ((rc= fh.insertRec(buf.array(), rid)) != RC.SUCCESS) {
			rmm.closeFile(fh);
			return rc;
		}
		
		SM_AttrcatRec.SM_SetAttrcatRec(attrcatRec, SM_Internal.RELCAT, 
				"attrCount", SM_RelcatRec.getAttrCountOffset(), 
				AttrType.INT, 4, -1);
		
		attrcatRec.storeAsBytes(buf);
		if ((rc= fh.insertRec(buf.array(), rid)) != RC.SUCCESS) {
			rmm.closeFile(fh);
			return rc;
		}
		
		SM_AttrcatRec.SM_SetAttrcatRec(attrcatRec, SM_Internal.RELCAT, 
				"indexCount", SM_RelcatRec.getIndexCountOffset(), 
				AttrType.INT, 4, -1);
		
		attrcatRec.storeAsBytes(buf);
		if ((rc= fh.insertRec(buf.array(), rid)) != RC.SUCCESS) {
			rmm.closeFile(fh);
			return rc;
		}
	   
		SM_AttrcatRec.SM_SetAttrcatRec(attrcatRec, SM_Internal.RELCAT, 
				"relName", SM_AttrcatRec.getRelNameOffset(), 
				AttrType.STRING, RedBase.MAXNAME, -1);
		
		attrcatRec.storeAsBytes(buf);
		if ((rc= fh.insertRec(buf.array(), rid)) != RC.SUCCESS) {
			rmm.closeFile(fh);
			return rc;
		}

		SM_AttrcatRec.SM_SetAttrcatRec(attrcatRec, SM_Internal.RELCAT, 
				"attrName", SM_AttrcatRec.getAttrNameOffset(), 
				AttrType.STRING, RedBase.MAXNAME, -1);
		
		attrcatRec.storeAsBytes(buf);
		if ((rc= fh.insertRec(buf.array(), rid)) != RC.SUCCESS) {
			rmm.closeFile(fh);
			return rc;
		}
		
		SM_AttrcatRec.SM_SetAttrcatRec(attrcatRec, SM_Internal.RELCAT, 
				"offset", SM_AttrcatRec.getOffsetOffset(), 
				AttrType.INT, 4, -1);
		
		attrcatRec.storeAsBytes(buf);
		if ((rc= fh.insertRec(buf.array(), rid)) != RC.SUCCESS) {
			rmm.closeFile(fh);
			return rc;
		}
		  
		SM_AttrcatRec.SM_SetAttrcatRec(attrcatRec, SM_Internal.RELCAT, 
				"attrType", SM_AttrcatRec.getAttrTypeOffset(), 
				AttrType.INT, 4, -1);
		
		attrcatRec.storeAsBytes(buf);
		if ((rc= fh.insertRec(buf.array(), rid)) != RC.SUCCESS) {
			rmm.closeFile(fh);
			return rc;
		}
		   
		SM_AttrcatRec.SM_SetAttrcatRec(attrcatRec, SM_Internal.RELCAT, 
				"attrLength", SM_AttrcatRec.getAttrLengthOffset(), 
				AttrType.INT, 4, -1);
		
		attrcatRec.storeAsBytes(buf);
		if ((rc= fh.insertRec(buf.array(), rid)) != RC.SUCCESS) {
			rmm.closeFile(fh);
			return rc;
		}

		SM_AttrcatRec.SM_SetAttrcatRec(attrcatRec, SM_Internal.RELCAT, 
				"indexNo", SM_AttrcatRec.getIndexNoOffset(), 
				AttrType.INT, 4, -1);
		
		attrcatRec.storeAsBytes(buf);
		if ((rc= fh.insertRec(buf.array(), rid)) != RC.SUCCESS) {
			rmm.closeFile(fh);
			return rc;
		}
		
		if ((rc= rmm.closeFile(fh)) != RC.SUCCESS)
			return rc;
		
		return RC.SUCCESS;
	}

	public boolean findDB(File f, String goal) {
		File[] names = f.listFiles();
		goal = f.toString() + "\\" + goal;
		boolean found = false;

		for (int i = 0; i < names.length && (!found); i++) {
			if (names[i].isDirectory()) {
				if (goal.equals(names[i].toString())) {
					found = true;
				}
			}
		}
		return found;
	}
	
	// createdb
	public  void createDB(String[] args) {
		RC rc= RC.SUCCESS;
		String dbname= null;
//		char[] command= new char[8 + SM_Internal.MAXDBNAME];
		
		// Look for 2 arguments. The first is always the name of the program
		// that was executed, and the second should be the name of the
		// database.
		if (args.length != 2) {
			System.err.println("Usage: " + args[0] + " DBname");
		}
		
		// The database name is the second argument
		dbname= args[1];

		// Sanity Check: Length of the argument should be less than MAXDBNAME
		//               DBname cannot contain ' ' or '/' 
		if (dbname.length() > SM_Internal.MAXDBNAME || dbname.matches(" ")
				|| dbname.matches("/")) {
			SM_Errors.printError(RC.SM_INVALIDDBNAME);
		}
		
		// Create a subdirectory for the database
		File f= new File(SM_Internal.DEFAULTPATH);
		if (this.findDB(f, dbname)) {
			System.err.println("The " + dbname + "folder exists.");
		} else {
			File nf= new File(SM_Internal.DEFAULTPATH + "//" + dbname);
			if (!nf.mkdir())
				System.err.println("createdb error");
		}

//		// Change the working directory
//		
//
//		   if (chdir(dbname) < 0) {
//		      SM_PrintError(SM_CHDIRFAILED);
//		      goto err_rm;
//		   }

		// Create the relation catalog
		if ((rc= createRelcat()) != RC.SUCCESS) {
			SM_Errors.printError(rc);
			f= new File(SM_Internal.DEFAULTPATH);
			File gf= new File(SM_Internal.DEFAULTPATH + "//" + dbname);
			if (!gf.delete())
				System.exit(1);
		}
	}

}
